import BlockType from "./BlockType.js";
import Point from "./Point.js";
import Grass from "./Grass.js";
import Water from "./Water.js";
import Wall from "./Wall.js";
import Tool from "./Tool.js";
import Tank from "./Tank.js";
import Config from "./Config.js";
import Direction from "./Direction.js";
import Area from "./Area.js";
import Enemy from "./enemy.js";

export default class Game {
    constructor(ctx) {
        this.blocks = [];
        this.context = ctx;
        this.controlKey = [];
        this.enemyArr = [];
        this.playerRocketArr = [];
        this.enemyRocketArr = [];
        this.enemyInterval = 10000;
    }
    init() {
        // 水平 horizontal  垂直-vertical
        let horizontalMax = Config.MapWidth / Config.BlockSize;
        let verticalMax = Config.MapHeight / Config.BlockSize;
        for (let j = 0; j < verticalMax; j++) {
            for (let i = 0; i < horizontalMax; i++) {
                let block = new Grass(i * Config.BlockSize, j * Config.BlockSize);
                this.blocks.push(block);
            }
        }
        //随机地生成砖块和水
        // 随机生成的总数
        let count = Tool.random(100, 150);
        for (let i = 0; i < count; i++) {
            let index = Tool.random(0, this.blocks.length - 1);
            let x = this.blocks[index].x;
            let y = this.blocks[index].y;
            let type = Tool.random(1, 2);
            switch (type) {
                case BlockType.Water:
                    this.blocks[index] = new Water(x, y);
                    break;
                case BlockType.Wall:
                    this.blocks[index] = new Wall(x, y);
                    break;
            }
        }
        // 生成玩家的坦克
        this.blocks[277] = new Grass(650, 550);
        this.tank = new Tank(650, 550);
        // 生成敌人
        this.blocks[0] = new Grass(0, 0);
        this.blocks[12] = new Grass(600, 0);
        this.blocks[23] = new Grass(1150, 0);
        this.enemyBirth();
    }
    enemyBirth() {
        let e1 = new Enemy(0, 0);
        this.enemyArr.push(e1);
        let e2 = new Enemy(600, 0);
        this.enemyArr.push(e2);
        let e3 = new Enemy(1150, 0);
        this.enemyArr.push(e3);
    }

    render() {
        this.context.clearRect(0, 0, Config.MapWidth, Config.MapHeight);

        for (let i = 0; i < this.blocks.length; i++) {
            this.blocks[i].render(this.context);
        }
        for (let i = 0; i < this.playerRocketArr.length; i++) {
            this.playerRocketArr[i].render(this.context);
        }
        this.tank.render(this.context);
        // 渲染敌人的子弹 
        this.enemyRocketArr.forEach((e) => {
            e.render(this.context);
        });
        // 渲染敌人
        for (let i = 0; i < this.enemyArr.length; i++) {
            this.enemyArr[i].render(this.context);
        }

    }

    update() {
        clearInterval(this.timer);
        this.timer = setInterval(function () {
            // 筛选出水和墙
            let wallAndWater = this.blocks.filter(function (e, i) {
                return e.blockType == BlockType.Wall || e.blockType == BlockType.Water;
            });

            // 计算tank的位移
            if (this.controlKey.length != 0) {
                // 获取最后一个控制按键
                let lastKey = this.controlKey[this.controlKey.length - 1];
                // 控制玩家坦克方向
                switch (lastKey) {
                    //w
                    case 87:
                        this.tank.direction = Direction.TOP;
                        this.tank.img.src = Config.ImageAssets.TankImgs.top;
                        break;
                        //a
                    case 65:
                        this.tank.direction = Direction.LEFT;
                        this.tank.img.src = Config.ImageAssets.TankImgs.left;
                        break;
                        //s
                    case 83:
                        this.tank.direction = Direction.BOTTOM;
                        this.tank.img.src = Config.ImageAssets.TankImgs.bottom;
                        break;
                        //d
                    case 68:
                        this.tank.direction = Direction.RIGHT;
                        this.tank.img.src = Config.ImageAssets.TankImgs.right;
                        break;
                }
                let collisionArr = wallAndWater.concat(this.enemyArr);
                this.tank.move(collisionArr);
            }

            // 控制玩家的tank开火
            if (this.playerShooting && this.tank.isWeaponReady) {
                let r = this.tank.shoot();
                this.playerRocketArr.push(r);
            }

            // 移动子弹
            for (let i = 0; i < this.playerRocketArr.length; i++) {
                let rocket = this.playerRocketArr[i];
                rocket.move();
                // 判断和砖块的碰撞                
                let walls = this.blocks.filter((e, i) => {
                    return e.blockType == BlockType.Wall;
                });
                walls.forEach(e => {
                    if (rocket.status == 'on' && e.isCollision(rocket)) {
                        rocket.explode();
                        e.life -= rocket.damage;
                        if (e.life <= 0) {
                            let index = this.blocks.indexOf(e);
                            this.blocks[index] = new Grass(e.x, e.y);
                        }
                    }
                });
                // 碰撞敌人
                this.enemyArr.forEach((e, i) => {
                    if (e.isCollision(rocket)) {
                        rocket.explode();
                        e.life -= rocket.damage;
                        if (e.life <= 0) {
                            this.enemyArr.splice(i, 1);
                        }
                    }
                });
            }


            // 移动敌人
            for (let i = 0; i < this.enemyArr.length; i++) {
                let enemySiblings = this.enemyArr.slice(0);
                let enemyIndex = enemySiblings.indexOf(this.enemyArr[i]);
                enemySiblings.splice(enemyIndex, 1);
                this.enemyArr[i].autoRun(enemySiblings.concat(wallAndWater, this.tank));

                if (this.enemyArr[i].isWeaponReady) {
                    let r = this.enemyArr[i].shoot(Config.ImageAssets.RocketImgs.enemy);
                    this.enemyRocketArr.push(r);
                }

            }
            // 移动敌人的子弹
            this.enemyRocketArr.forEach((e) => {
                let rocket = e;
                rocket.move();
                // 判断和砖块的碰撞                
                let walls = this.blocks.filter((e, i) => {
                    return e.blockType == BlockType.Wall;
                });
                walls.forEach(e => {
                    if (rocket.status == 'on' && e.isCollision(rocket)) {
                        rocket.explode();
                        e.life -= rocket.damage;
                        if (e.life <= 0) {
                            let index = this.blocks.indexOf(e);
                            this.blocks[index] = new Grass(e.x, e.y);
                        }
                    }
                });
                // 击中玩家的坦克
                if (rocket.isCollision(this.tank)) {
                    rocket.explode();
                    this.tank.life -= rocket.damage;
                    if (this.tank.life <= 0) {
                        //游戏结束
                        clearInterval(this.timer);
                        setTimeout((() => {
                            this.gameOver();
                        }).bind(this), 200);
                    }
                }
            });

            // 生成敌人
            this.enemyInterval -= Config.GameUpdateTick;
            if (this.enemyInterval <= 0) {
                this.enemyBirth();
                this.enemyInterval = 10000;
            }
            this.render();
            this.distoyDeathRocket();
        }.bind(this), Config.GameUpdateTick);
    }



    distoyDeathRocket() {
        for (let i = 0; i < this.playerRocketArr.length; i++) {
            let rocket = this.playerRocketArr[i];
            if (rocket.x + rocket.width < 0 || rocket.y + rocket.height < 0 || rocket.x > 1400 || rocket.y > 800) {
                let index = this.playerRocketArr.indexOf(rocket);
                this.playerRocketArr.splice(index, 1);
            }
            if (rocket.status == 'die') {
                let index = this.playerRocketArr.indexOf(rocket);
                this.playerRocketArr.splice(index, 1);
            }
        }
        this.enemyRocketArr.forEach((e) => {
            let rocket = e;
            if (rocket.x + rocket.width < 0 || rocket.y + rocket.height < 0 || rocket.x > 1400 || rocket.y > 800) {
                let index = this.enemyRocketArr.indexOf(rocket);
                this.enemyRocketArr.splice(index, 1);
            }
            if (rocket.status == 'die') {
                let index = this.enemyRocketArr.indexOf(rocket);
                this.enemyRocketArr.splice(index, 1);
            }
        });
    }

    keyControl() {
        document.addEventListener('keydown', function (e) {
            // 方向控制 
            if ([87, 65, 83, 68].indexOf(e.keyCode) != -1) {
                if (this.controlKey.indexOf(e.keyCode) == -1) {
                    this.controlKey.push(e.keyCode)
                }
            }
        }.bind(this));

        document.addEventListener('keypress', function (e) {
            // 开火
            if (e.keyCode == 32) {
                // let rocket = this.tank.shoot();
                // this.playerRocketArr.push(rocket);
                if (!this.playerShooting) {
                    // this.shootInterval = this.tank.attackSpeed;
                    this.shootInterval = 0;
                    this.playerShooting = true;
                }
            }
        }.bind(this))

        document.addEventListener('keyup', function (e) {
            if (this.controlKey.indexOf(e.keyCode) != -1) {
                let index = this.controlKey.indexOf(e.keyCode);
                this.controlKey.splice(index, 1);
            }
            if (e.keyCode == 32) {
                this.playerShooting = false;
            }
        }.bind(this));
    }

    gameOver() {
        this.render();
        this.context.fillStyle = 'red';
        this.context.font = "200px consolas";
        this.context.fillText("GAME OVER", 120, 300);
    }
}